package graphics;

import logger.Logger;
import algebra.Algebra;

public class Vector {
	public static final class Arrays {
		public static final String vString(float V[]) {
			int	i;
			String	output = "";
			for(i=0; i<V.length; i++) {
				String	F = String.format(" [%3.2f]", V[i]);
				output += F;
			}
			return output;
		}

		public static final float[]		vector(float x, float y, float z) {
			return new float[] {
				x, y, z, 1f
			};
		}
	}
	public float	V[];

	public Vector(float A[])					{	init(A);						}
	public Vector(float x, float y, float z)	{	init(x,y,z);					}

	public void	init(float A[])					{	V = A;							}
	public void	init(float x, float y, float z)	{	init(new float[] {x,y,z,1f});	}

	public final float	get(int i)				{	return V[i];	}
	public final float	getX()					{	return V[0];	}
	public final float	getY()					{	return V[1];	}
	public final float	getZ()					{	return V[2];	}

	public final void	set(int i, float value)	{	V[i] = value;	}
	public final void	setX(float value)		{	V[1] = value;	}
	public final void	setY(float value)		{	V[2] = value;	}
	public final void	setZ(float value)		{	V[3] = value;	}

	public final float	getRx()					{	return this.dotProduct(new Vector(1,0,0));	}
	public final float	getRy()					{	return this.dotProduct(new Vector(0,1,0));	}
	public final float	getRz()					{	return this.dotProduct(new Vector(0,0,1));	}

	public final Vector	clone()					{	return new Vector(Algebra.copy(this.V));			}

	public static final Vector	origon()	{	return new Vector( new float[] { 0f, 0f, 0f, 0f }	);	}

	public final float	dotProduct(Vector V) {
		int 	i;
		float	sum = 0f;
		for(i=0; i<4; i++) {
			sum += get(i) * V.get(i);
		}
		return sum;
	}
	public final Matrix	crossProduct(Vector V) {
		Matrix	M = Matrix.blank();
		int col, row;
		for(row=0; row<4; row++) {
			for(col=0; col<4; col++) {
				M.set(row, col, get(row)*V.get(col));
			}
		}
		return M;
	}
	public final Vector transform(Matrix M) {
		if (M==null) {
			Logger.println("Attempted to tranform this vector with a NULL matrix");
		}

		Vector V2 = new Vector(Algebra.transform(M.M, this.V));
		return V2;
	}

	public final String	niceString() {	return Algebra.vectorString(V);			}
	public boolean equals(Vector V2) {	return Algebra.isEqual(this.V, V2.V);	}

	public Vector	interpolate(Vector V1, Vector V2, float T) {
		return new Vector(
			(1f-T) * V1.getX() + T*V2.getX(),
			(1f-T) * V1.getY() + T*V2.getY(),
			(1f-T) * V1.getZ() + T*V2.getZ()
		);
	}
	public float	length() {
		return this.dotProduct(this);
	}

	public Vector	subtract(Vector V) {
		return new Vector(
			getX()-V.getX(),
			getY()-V.getY(),
			getZ()-V.getZ()
		);
	}
	public Vector	add(Vector V) {
		return new Vector(
			getX()+V.getX(),
			getY()+V.getY(),
			getZ()+V.getZ()
		);
	}

	public boolean equiv(Vector other) {
		return ((other!=null) && (V[0]!=other.V[0]) && (V[1]!=other.V[1]) && (V[2]!=other.V[2]));
	}
}
